//<<<+++OPENSOURCE
//<<<+++OPENSOURCE_LICENSE
/**
 * @addtogroup FPDFAPI
 * @{
 */

/**
 * @file
 * @brief PDF render classes.
 */

//<<<+++OPENSOURCE_MUST_BEGIN
#ifndef _FPDF_RENDER_
#define _FPDF_RENDER_

#ifndef _FPDF_PAGE_
#include "fpdf_page.h"
#endif

#ifndef _FX_GE_H_
#include "../fxge/fx_ge.h"
#endif
//<<<+++OPENSOURCE_MUST_END

/** Classes defined in this header file */
class CPDF_RenderContext;
class CPDF_RenderOptions;
class CPDF_ImageCache;
class IPDF_OCContext;
class CPDF_QuickStretcher;

/** Classes referred in this header file */
class CFX_PathData;
class CFX_GraphStateData;
class CFX_RenderDevice;
class CPDF_TextObject;
class CPDF_PathObject;
class CPDF_ImageObject;
class CPDF_ShadingObject;
class CPDF_FormObject;

/** @brief PDF optional content context interface. */ 
class IPDF_OCContext
{
public:
	/**
	 * Virtual destructor, derived classes could be destroyed by this interface.
	 */
	virtual ~IPDF_OCContext() {}

	/**
	 * Check whether a option content group is visible.
	 *
	 * @param[in] pOCG			The optional content group dictionary.
	 * @return Non-zero means visible, otherwise invisible. 
	 */
	virtual FX_BOOL	CheckOCGVisible(const CPDF_Dictionary* pOCG) = 0;

	/** 
	 * Check whether an object is visible in this context
	 *
	 * @param[in] pObj			Page object.
	 * @return Non-zero means visible, otherwise invisible. 
	 */
	FX_BOOL CheckObjectVisible(const CPDF_PageObject* pObj);
};

/**
 * @name Codes for CPDF_RenderOptions::m_ColorMode.
 */
/*@{*/

/** @brief Normal color mode. */
#define RENDER_COLOR_NORMAL		0
/** @brief Gray color mode: map colors to background/foreground. */
#define RENDER_COLOR_GRAY		1
/** @brief Two color mode: map white/black to background/foreground, other unchanged. */
#define RENDER_COLOR_TWOCOLOR	2
/** @brief Output alpha only, ignore color. */
#define RENDER_COLOR_ALPHA		3
/*@}*/

/**
 * @name Bitmasks for CPDF_RenderOption::m_Flags.
 */
/*@{*/

/** @brief Use ClearType-like anti-aliasing to render text objects, this flag is set in default. */
#define RENDER_CLEARTYPE			0x00000001
/** @brief Always output text as graphics (path or bitmap), don't allow device font substitution. */
#define RENDER_PRINTGRAPHICTEXT		0x00000002
/** @brief Always use downsampling for image stretching. */
#define RENDER_FORCE_DOWNSAMPLE		0x00000004
/** @brief Print preview mode. */
#define RENDER_PRINTPREVIEW			0x00000008
/** @brief For clear type: choose BGR stripe device (most device using RGB). */
#define RENDER_BGR_STRIPE			0x00000010
/** @brief Disable native text rendering feature (like GDI+) */
#define RENDER_NO_NATIVETEXT		0x00000020
/** @brief Always use halftone for image stretching. */
#define RENDER_FORCE_HALFTONE		0x00000040
/** @brief Always use anti-aliasing for rectangle drawing. */
#define RENDER_RECT_AA				0x00000080
/** @brief Always use aliasing for path drawing. */
#define RENDER_FILL_FULLCOVER		0x00000100
/** @brief Always output text as bitmap in less than 50 font size case, use for epson stylus printer or other specified printers. */
#define RENDER_PRINTIMAGETEXT       0x00000200
/** @brief Using overprint to render page. */
#define RENDER_OVERPRINT            0x00000400
/** @brief Using thin line for path drawing. */
#define RENDER_THINLINE             0x00000800
//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/** @brief enhance zero line. */
#define RENDER_ENHANCEZEROLINE		0x00001000
//<<<+++OPENSOURCE_END
/** @brief Do not use anti-aliasing to render text objects, this flag doesn't set in default. */
#define RENDER_NOTEXTSMOOTH			0x10000000
/** @brief Do not use anti-aliasing to render path objects, this flag doesn't set in default. */
#define RENDER_NOPATHSMOOTH			0x20000000
/** @brief Do not smooth images when render image objects, this flag doesn't set in default. */
#define RENDER_NOIMAGESMOOTH		0x40000000
/** @brief Limit image cache size. */
#define RENDER_LIMITEDIMAGECACHE	0x80000000

/*@}*/

/** @brief Page rendering options. */
class CPDF_RenderOptions : public CFX_Object
{
public:
	/** Default constructor. */
	CPDF_RenderOptions();

	/** Display mode mode (default: #RENDER_COLOR_NORMAL). */
	int				m_ColorMode;
	/** The background color for gray mode (default: white). */
	FX_COLORREF		m_BackColor;
	/** The foreground color for gray mode (default: black). */
	FX_COLORREF		m_ForeColor;
	/** Render flags. */
	FX_DWORD		m_Flags;
	/**
	 * Image interpolation, default value is 0:
	 *     -1 means to disable image interpolation;
	 *     0 means to apply according to "Interpolate" key value in image dictionary;
	 *     1 means to use image interpolation anyway.
	 */
	int				m_Interpolation;
	/** Additional flags depending on the device. */
	FX_DWORD		m_AddFlags;
	/** Optional content context interface. */
	IPDF_OCContext*	m_pOCContext;
	/** Specifies the limitation size of large image cache, in bytes, default is 100MB. */
	FX_DWORD		m_dwLimitCacheSize;
	/** Halftone limit. */
	int				m_HalftoneLimit;

	/**
	 * Translate a color.
	 *
	 * @param[in] argb			The input color.
	 * @return The translated color. 
	 */
	FX_ARGB			TranslateColor(FX_ARGB argb) const;
};

/**
 * @brief Context for rendering a PDF page or a list of page objects.
 *
 * A PDF page can be divided into different layers, including the page content, annotations, and interactive form.
 * It's important to keep information about those layers if backdrop generation is required during transparency
 * rendering for devices not capable of fetching background.
 * 
 * A PDF rendering context also makes use of page caches, additional page resources, and rendering options.
 */
class CPDF_RenderContext : public CFX_Object
{
public:
	/** Default constructor. */
	CPDF_RenderContext();

	/**
	 * Construct a context for rendering a PDF page.
	 *
	 * @param[in] pPage			The input page.
	 * @param[in] bFirstLayer	Whether it's the first layer.
	 */
	void			Create(CPDF_Page* pPage, FX_BOOL bFirstLayer = TRUE);

	/**
	 * Construct a general purpose context (for rendering page, form, stream, or whatever).
	 * All parameters can be optional.
	 *
	 * @param[in] pDoc				The PDF document.
	 * @param[in] pPageCache		The page render cache.
	 * @param[in] pPageResources	The Resources dictionary.
	 * @param[in] bFirstLayer		Whether it's the first layer.
	 */
	void			Create(CPDF_Document* pDoc = NULL, CPDF_PageRenderCache* pPageCache = NULL,
						CPDF_Dictionary* pPageResources = NULL, FX_BOOL bFirstLayer = TRUE);

	/** The destructor. */
	~CPDF_RenderContext();

	/** Clear state. */
	void			Clear();

    //<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**
	 * Draw a page description stream.
	 *
	 * @param[out] pDevice			The output device.
	 * @param[in] pStreamData		The page description stream buffer.
	 * @param[in] stream_size		The size in bytes of the page description stream. -1 for NULL terminated byte string.
	 * @param[in] pDisplayMatrix	The matrix from stream coords to device coords. Can be NULL if no transformation needed.

	 */
	void			DrawStream(CFX_RenderDevice* pDevice,
						const void* pStreamData, FX_DWORD stream_size,
						const CFX_AffineMatrix* pDisplayMatrix = NULL);
    //<<<+++OPENSOURCE_END
	/**
	 * Append a list of page objects to the current layer.
	 *
	 * @param[in] pObjs				The input page objects.
	 * @param[in] pObject2Device	The matrix from object coords to device coords.
	 */
	void			AppendObjectList(CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObject2Device);

	/**
	 * Set custom background drawing.
	 *
	 * @param[in] pBackground		The background drawing interface.
	 */
	void			SetBackground(class IPDF_BackgroundDraw* pBackground);


	/**
	 * Do the real rendering. 
	 * Optionally, rendering matrix can be modified by the last matrix.
	 *
	 * @param[out] pDevice			The output device.
	 * @param[in] pOptions			The render options.
	 * @param[in] pFinalMatrix		The final matrix to transform the result.
	 */
	void			Render(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions = NULL, 
						const CFX_AffineMatrix* pFinalMatrix = NULL);

	/**
	 * Draw a list of page objects.
	 *
	 * @param[out] pDevice			The output device.
	 * @param[in] pObjs				The input page objects list.
	 * @param[in] pObject2Device	The matrix from object coords to device coords.
	 * @param[in] pOptions			The render options.
	 */
	void			DrawObjectList(CFX_RenderDevice* pDevice, CPDF_PageObjects* pObjs, 
						const CFX_AffineMatrix* pObject2Device, const CPDF_RenderOptions* pOptions);
    //<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	/**
	 * Draw a rough preview (quick draw).
	 *
	 * @param[out] pDevice			The output device.
	 */
	void			QuickDraw(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions = NULL);
    //<<<+++OPENSOURCE_END
    
	/**
	 * Get background of a page object within the rendering context.
	 *
	 * @param[out] pBuffer			It receives the background bitmap.
	 * @param[in] pObj				The input page object.
	 * @param[in] pOptions			The render options.
	 * @param[in] pFinalMatrix		The matrix from object coords to device coords.
	 */
	void			GetBackground(CFX_DIBitmap* pBuffer, const CPDF_PageObject* pObj, 
						const CPDF_RenderOptions* pOptions, CFX_AffineMatrix* pFinalMatrix);

	/** Get the page render cache. */
	CPDF_PageRenderCache*	GetPageCache() const { return m_pPageCache; }

	/**
	 * @name Rendering environment.
	 */
	/*@{*/

	/** The PDF document. might be NULL! */
	CPDF_Document*			m_pDocument;
	/** The Resources dictionary. might be NULL! */
	CPDF_Dictionary*		m_pPageResources;
	/** The page render cache. might be NULL! */
	CPDF_PageRenderCache*	m_pPageCache;

	/*@}*/

protected:
	/** The rendering contents. */
	CFX_ArrayTemplate<struct _PDF_RenderItem>	m_ContentList;

	/** The background drawing interface. */
	IPDF_BackgroundDraw*	m_pBackgroundDraw;
	/** Whether it's the first layer. */
	FX_BOOL					m_bFirstLayer;


	/**
	 * Render a page object.
	 *
	 * @param[out] pDevice		The output device.
	 * @param[in] pStopObj		The page object to render.
	 * @param[in] pOptions		The render options.
	 * @param[in] pFinalMatrix	The matrix from object coords to device coords.
	 */
	void			Render(CFX_RenderDevice* pDevice, const CPDF_PageObject* pStopObj, 
							const CPDF_RenderOptions* pOptions, const CFX_AffineMatrix* pFinalMatrix);

	friend class CPDF_RenderStatus;
	friend class CPDF_ProgressiveRenderer;
    //<<<+++OPENSOURCE_BEGIN LIC==FOXIT
	friend class CPDF_QuickDrawer;
    //<<<+++OPENSOURCE_END
};

//<<<+++OPENSOURCE_BEGIN LIC==FOXIT
/** @brief PDF quick drawer class. */
class CPDF_QuickDrawer : public CFX_Object
{
public:
	CPDF_QuickDrawer();
	~CPDF_QuickDrawer();

	/**
	 * Start the quick drawing.
	 *
	 * @param[in] pContext			The render context.
	 * @param[out] pDevice			The output device.
	 */
	void			Start(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions = NULL, CPDF_Dictionary* pResource = NULL);
	/**
	 * Continue the quick drawing.
	 *
	 * @param[in] pPause			The pause interface.
	 * @return Non-zero means to be continued.
	 */
	FX_BOOL			Continue(IFX_Pause* pPause);

protected:
	/**
	 * Quick draw a list of page objects.
	 *
	 * @param[in] pObjs				The input page objects list.
	 * @param[in] pMatrix			The matrix from objects coords to device coords.
	 */
	void			QuickDrawObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pMatrix);

	/**
	 * Quick draw a path object.
	 *
	 * @param[in] pPathObj			The input path object.
	 */
	void			QuickDrawPath(CPDF_PathObject* pPathObj);
	/**
	 * Quick draw an image object.
	 *
	 * @param[in] pImageObj			The input image object.
	 */
	FX_BOOL			QuickDrawImage(CPDF_ImageObject* pImageObj, IFX_Pause* pPause);
	/**
	 * Quick draw a form object.
	 *
	 * @param[in] pFormObj			The input form object.
	 */
	void			QuickDrawForm(CPDF_FormObject* pFormObj);
	/**
	 * Quick draw a shading object.
	 *
	 * @param[in] pShadingObj		The input shading object.
	 */
	void			QuickDrawShading(CPDF_ShadingObject* pShadingObj);
	/**
	 * Quick draw a text object.
	 *
	 * @param[in] textobj			The input text object.
	 */
	void			QuickDrawText(CPDF_TextObject* textobj);

	/**
	 * Quick stroke a path.
	 *
	 * @param[in] pPath				The input path data.
	 * @param[in] pMatrix			The path matrix.
	 * @param[in] argb				The stroke color.
	 */
	void			QuickStroke(const CFX_PathData* pPath, const CFX_AffineMatrix* pMatrix, FX_ARGB argb);

	/** The render context. */
	CPDF_RenderContext*		m_pContext;
	/** The output device. */
	CFX_RenderDevice*		m_pDevice;
	/** The current layer index. */
	FX_DWORD				m_LayerIndex;
	/** The current object index. */
	FX_DWORD				m_ObjectIndex;
	/** The quick draw matrix. */
	CFX_AffineMatrix		m_Matrix;
	/** For big image drawing */
	CPDF_QuickStretcher*	m_pQuickStretcher;
	/** The render options. */
	const CPDF_RenderOptions* m_pOptions;
    /** The resources dictionary. */
    CPDF_Dictionary*  m_pResources;
};
//<<<+++OPENSOURCE_END

/** @brief PDF background drawing interface. */
class IPDF_BackgroundDraw
{
public:
	/**
	 * For custom background PDF rendering on a non-display device (like printers), it's often not possible
	 * for rendering engine to get a background (for masked operations or transparent operations), therefore
	 * the rendering application has to provide a routine to draw the custom background into a bitmap device.
	 * In most cases, only portion of the background is needed. 
	 * Default implementation fills white color.
	 *
	 * NOTE: the bitmap device for rendering background might have different resolution from the original device,
	 * for example, in order to reduce spooling size, we use lower resolution for rendering shading areas and
	 * transparent images.
	 *
	 * @param[in] pBitmapDevice		The temporary bitmap device. The size of this device
	 *								can be only portion of the rendering target device.
	 * @param[in] pOriginal2Bitmap	The matrix from original device space to bitmap device space.
	 */
	virtual	void	OnDrawBackground(
						CFX_RenderDevice* pBitmapDevice,
						const CFX_AffineMatrix* pOriginal2Bitmap
						) = 0;
};

/**
 * @brief PDF progressive renderer.
 *
 * A progressive renderer that breaks the full rendering process into steps.
 * This class must be overloaded in order to pause a step whenever the application thinks necessary.
 * 
 * Application must first call Start() to start the rendering, then, when it's paused, the application
 * must call Continue() to continue the rendering, until status becomes Done or Failed.
 * 
 * To stop the rendering, simply destruct the renderer.
 */
class CPDF_ProgressiveRenderer : public CFX_Object
{
public:
	/** Default constructor. */
	CPDF_ProgressiveRenderer();
	/** The destructor. */
	~CPDF_ProgressiveRenderer();

	/** @brief Render status. */
	typedef enum {
		Ready,				/**< Ready. */
		ToBeContinued,		/**< To be continued. */
		Done,				/**< Done. */
		Failed				/**< Failed. */
	} RenderStatus;

	/** Get the render status. */
	RenderStatus		GetStatus() { return m_Status; }

	/**
	 * @name NOTE: between Start() and Continue() calls, the application should not alter
	 * any status (clipping) of the device.
	 */
	/*@{*/

	/**
	 * Start rendering.
	 *
	 * @param[in] pContext			The render context.
	 * @param[out] pDevice			The output device.
	 * @param[in] pOptions			The render options.
	 * @param[in] pPause			The pause interface.
	 */
	void				Start(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, 
							const CPDF_RenderOptions* pOptions, class IFX_Pause* pPause, FX_BOOL bDropObjects = FALSE);
	/**
	 * Continue rendering.
	 *
	 * @param[in] pPause			The pause interface.
	 */
	void				Continue(class IFX_Pause* pPause);

	/*@}*/

	/** Return an estimated percentage of progress. */
	int					EstimateProgress();

	/** Get ready for next rendering. */
	void				Clear();

protected:
	/** The render status. */
	RenderStatus		m_Status;

	/** The render context. */
	CPDF_RenderContext*	m_pContext;
	/** The output device. */
	CFX_RenderDevice*	m_pDevice;
	/** The render options. */
	const CPDF_RenderOptions*	m_pOptions;
	/** Whether drop objects once it's rendered. USE WITH CARE! */
	FX_BOOL				m_bDropObjects;

	/** The render status interface. */
	class CPDF_RenderStatus*	m_pRenderer;
	/** The clipping rectangle. */
	CFX_FloatRect		m_ClipRect;

	/** The current layer index. */
	FX_DWORD			m_LayerIndex;
	/** The current object index. */
	FX_DWORD			m_ObjectIndex;
	/** The current object position. */
	FX_POSITION			m_ObjectPos;
	/** The immediate previous last position. */
	FX_POSITION			m_PrevLastPos;

	/** Render a step. */
	void				RenderStep();
};

/**
 * @brief Utility object for text rendering
 *
 */
class CPDF_TextRenderer : public CFX_Object
{
public:
	/**
	 * Draw a text string, using Windows style parameters.
	 *
	 * @param[in] pDevice			output device.
	 * @param[in] left				x position, in device coord.
	 * @param[in] top				y position, in device coord.
	 * @param[in] pFont				font.
	 * @param[in] height			height of the character cell, in pixels.
	 * @param[in] str				a string using font encoding.
	 * @param[in] argb				color and alpha value, in 0xaarrggbb format.
	 */
	static void		DrawTextString(CFX_RenderDevice* pDevice, int left, int top,
						CPDF_Font* pFont,
						int height,
						const CFX_ByteString& str, 
						FX_ARGB argb);

	/**
	 * Draw a text string using PDF style parameters.
	 *
	 * @param[in] pDevice			output device.
	 * @param[in] origin_x			x position of the origin (for first character), in device coord.
	 * @param[in] origin_y			y position of the origin (for first character), in device coord.
	 * @param[in] pFont				font.
	 * @param[in] font_size			number of points for the font em square.
	 * @param[in] matrix			a matrix from text space to device space, used for font rotation,
	 *								scaling and skewing. Can be NULL for identity matrix.
	 *								If specified, the "e" and "f" coefficients (for translation) are ignored.
	 * @param[in] str				a string using font encoding.
	 * @param[in] fill_argb			color and alpha value, in 0xaarrggbb format. 0 for not filling.
	 * @param[in] stroke_argb		color for stroking text. 0 for not stroking.
	 * @param[in] pGraphState		required for stroking.
	 * @param[in] pOptions			rendering options, like cleartype flag
	 */
	static void		DrawTextString(CFX_RenderDevice* pDevice, FX_FLOAT origin_x, FX_FLOAT origin_y,
						CPDF_Font* pFont,
						FX_FLOAT font_size,
						const CFX_AffineMatrix* matrix,
						const CFX_ByteString& str,
						FX_ARGB fill_argb,
						FX_ARGB stroke_argb = 0,
						const CFX_GraphStateData* pGraphState = NULL,
						const CPDF_RenderOptions* pOptions = NULL
						);

	/**
	 * Draw text path.
	 *
	 * @param[in] pDevice			output device.
	 * @param[in] nChars			The number of characters in the text.
	 * @param[in] pCharCodes		The character codes.
	 * @param[in] pCharPos			The character positions.
	 * @param[in] pFont				font.
	 * @param[in]  font_size		The font size.
	 * @param[in] pText2User		The matrix from text coords to user coords.
	 * @param[in] pUser2Device		The matrix from user coords  to user coords.
	 * @param[in] pGraphState		graphic state, for pen attributes.
	 * @param[in] fill_argb			Fill color.
	 * @param[in] stroke_argb		Stroke color.
	 * @param[in] pClippingPath		The clipping path to add to.
	 * @param[in] nFlag				Some flags for fill and stroke rule.
	 * @return Non-zero means success, otherwise failure.
	 */
	static FX_BOOL	DrawTextPath(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, 
						CPDF_Font* pFont, FX_FLOAT font_size, 
						const CFX_AffineMatrix* pText2User, const CFX_AffineMatrix* pUser2Device, 
						const CFX_GraphStateData* pGraphState,
						FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag = 0);

	/**
	 * Draw normal text.
	 *
	 * @param[in] pDevice			output device.
	 * @param[in] nChars			The number of characters in the text.
	 * @param[in] pCharCodes		The character codes.
	 * @param[in] pCharPos			The character positions.
	 * @param[in] pFont				font.
	 * @param[in] font_size			The font size.
	 * @param[in] pText2Device		The matrix from text coords to device coords.
	 * @param[in] fill_argb			The fill color.
	 * @param[in] pOptions			The render options.
	 * @return Non-zero means success, otherwise failure.
	 */
	static FX_BOOL	DrawNormalText(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, 
						CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device, 
						FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions);

	/**
	 * Draw type3 text.
	 *
	 * @param[in] pDevice			output device.
	 * @param[in] nChars			The number of characters in the text.
	 * @param[in] pCharCodes		The character codes.
	 * @param[in] pCharPos			The character positions.
	 * @param[in] pFont				font.
	 * @param[in] font_size			The font size.
	 * @param[in] pText2Device		The matrix from text coords to device coords.
	 * @param[in] fill_argb			The fill color.
	 * @return Non-zero means success, otherwise failure.
	 */
	static FX_BOOL	DrawType3Text(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, 
						CPDF_Font* pFont, FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device, 
						FX_ARGB fill_argb);
};

/** @brief Cache management for rendered page image. */
class IPDF_PageImageCache
{
public:
	/** Create a page image cache. */
	static IPDF_PageImageCache* Create();
	/** The destructor. */
	virtual ~IPDF_PageImageCache() {}

	/**
	 * Output page.
	 *
	 * @param[out] pDevice				The output device.
	 * @param[in] pPage					The page.
	 * @param[in] pos_x					The x-coordinate in device coords.
	 * @param[in] pos_y					The y-coordinate in device coords.
	 * @param[in] size_x				The horizontal size in device coords.
	 * @param[in] size_y				The vertical size in device coords.
	 * @param[in] rotate				The rotation degrees of the page.
	 */
	virtual void		OutputPage(CFX_RenderDevice* pDevice, CPDF_Page* pPage,
								int pos_x, int pos_y, int size_x, int size_y, int rotate) = 0;
	/**
	 * Set the cache limit.
	 *
	 * @param[in] limit					limit is number of bytes	
	 */
	virtual void		SetCacheLimit(FX_DWORD limit) = 0;
};

/** Store all dispensable items used when rendering a page */
// Currently we have image cache only
class CPDF_PageRenderCache : public CFX_Object
{
public:
	CPDF_PageRenderCache(CPDF_Page* pPage) { 
		m_pPage = pPage;
		m_nTimeCount = 0;
		m_nCacheSize = 0;
		m_pCurImageCache = NULL;
		m_bCurFindCache = FALSE;
        m_pCurImageCaches = NULL;
	}
	~CPDF_PageRenderCache() { ClearAll(); }

	void				ClearAll();
	void				ClearImageData();

	/** Get estimated size of the total cache. The application can use some strategy
	    for dispense page caches according the memory size they occupy.
	*/
	FX_DWORD			EstimateSize();

	void				CacheOptimization(FX_INT32 dwLimitCacheSize);
	FX_DWORD			GetCachedSize(CPDF_Stream* pStream) const;
	FX_DWORD			GetTimeCount() const { return m_nTimeCount; }
	void				SetTimeCount(FX_DWORD dwTimeCount) { m_nTimeCount = dwTimeCount; }

	/** Get cached items */
	void				GetCachedBitmap(CPDF_Stream* pStream, CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor,
                                        FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask= FALSE,
                                        CPDF_RenderStatus* pRenderStatus = NULL, FX_INT32 downsampleWidth = 0, FX_INT32 downsampleHeight = 0);

	/** Reset the image cache or force the cache to be expired */
	void				ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap);

	void				ClearImageCache(CPDF_Stream* pStream);
	CPDF_Page*			GetPage() { return m_pPage; }

	CFX_MapPtrToPtr		m_ImageCaches;		// Mapping from CPDF_Image* to CPDF_ImageCache*
public:
	// For progressive processing.
	FX_BOOL				StartGetCachedBitmap(CPDF_Stream* pStream, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0,
                                            FX_BOOL bLoadMask= FALSE, CPDF_RenderStatus* pRenderStatus = NULL,
                                            FX_INT32 downsampleWidth = 0, FX_INT32 downsampleHeight = 0);
	
	FX_BOOL				Continue(IFX_Pause* pPause);
	CPDF_ImageCache*	m_pCurImageCache;
    CFX_PtrArray*       m_pCurImageCaches;
protected:
	friend class		CPDF_Page;

	CPDF_Page*			m_pPage;
	
	FX_DWORD			m_nTimeCount;
	FX_DWORD			m_nCacheSize;
	FX_BOOL				m_bCurFindCache;
};

class CPDF_RenderConfig : public CFX_Object
{
public:
	CPDF_RenderConfig();
	~CPDF_RenderConfig();

	int					m_HalftoneLimit;
	int					m_RenderStepLimit;
};

//<<<+++OPENSOURCE_MUST_BEGIN
#endif // _FPDF_RENDER_
//<<<+++OPENSOURCE_MUST_END

/** @} */



